extends Node

signal camera_should_shake(amount: float)

# 场景信息
# 场景名称 = { 
#	enemies_alive => [ 敌人的路径 ]
# }
var world_stats = {}

var SAVE_PATH = "user://data.sav"

@onready var player_stats: Stats = $PlayerStats
@onready var color_rect: ColorRect = $ColorRect
@onready var deault_player_stats := player_stats.to_dict()

@export var title_screen_path: String = "res://scenes/ui/title_screen.tscn"
@export var new_game_scene_path: String = "res://scenes/worlds/forest.tscn"

func _ready() -> void:
	color_rect.color.a = 0

func change_scene(path: String, params:= {}) -> void:
	var tree := get_tree()
	# 停止画面
	tree.paused = true
	
	var tween := create_tween()
	tween.set_pause_mode(Tween.TWEEN_PAUSE_PROCESS)
	# 补间动画，设置挡板透明的遮住过度动画
	tween.tween_property(color_rect, "color:a", 1, 0.2)
	await tween.finished

	if tree.current_scene is World:
		# 存储场景信息
		var old_world_name := tree.current_scene.scene_file_path.get_file().get_basename()
		world_stats[old_world_name] = tree.current_scene.to_dict()

	# 转场
	tree.change_scene_to_file(path)
	await tree.tree_changed

	# 执行回调方法
	if "init" in params:
		params.init.call()
	
	if tree.current_scene is World:
		# 加载场景信息
		var new_world_name = tree.current_scene.scene_file_path.get_file().get_basename()
		if new_world_name in world_stats:
			tree.current_scene.from_dict(world_stats[new_world_name])
		
		# 根据参数更新玩家位置
		if "position" in params:
			tree.current_scene.update_player(params.position, params.direction)
		elif "entryPoint" in params:
			for node in tree.get_nodes_in_group("entry_points"):
				node = node as EntryPoint
				if node.name == params.entryPoint:
					tree.current_scene.update_player(node.global_position, node.direction)
					break

	# 随用随取
	create_tween().tween_property(color_rect, "color:a", 0, 0.2)
	
	tree.paused = false
	
# 存档
func save_game() -> void:
	# 场景数据
	var scene := get_tree().current_scene
	var scene_name := scene.scene_file_path.get_file().get_basename()
	world_stats[scene_name] = scene.to_dict()

	var data = {
		world_stats = world_stats,
		player_stats = player_stats.to_dict(),
		scene_path = scene.scene_file_path,
		player = {
			direction = scene.player.direction,
			position = {
				x = scene.player.global_position.x,
				y = scene.player.global_position.y,
			}
		},
	}
	
	# 写入文件
	var json := JSON.stringify(data)
	var file = FileAccess.open(SAVE_PATH, FileAccess.WRITE)
	if not file:
		return
	else:
		file.store_string(json)

func new_game() -> void:
	change_scene(new_game_scene_path, {
		init = func ():
			world_stats = {}
			player_stats.from_dict(deault_player_stats)
	})

func load_game() -> void:
	var file = FileAccess.open(SAVE_PATH, FileAccess.READ)
	if not file:
		return
		
	var json := file.get_as_text()
	var data := JSON.parse_string(json) as Dictionary

	change_scene(data.scene_path, {
		direction = data.player.direction,
		position = Vector2(
			data.player.position.x,
			data.player.position.y
		),
		init = func ():
			world_stats = data.world_stats
			player_stats.from_dict(data.player_stats)
	})

func back_to_title() -> void:
	change_scene(title_screen_path)

func shake_camera(amount: float) -> void:
	camera_should_shake.emit(amount)

func has_save() -> bool:
	return FileAccess.file_exists(SAVE_PATH)
